#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>


/* name of the carpark */
#define CAR_PARK "Phoenix Car Park"
/* max number of cars the carpark can hold */
#define CAR_PARK_SIZE 10
/* prob of arrival of car */
#define ARRIVAL_PERCENT_ACTION 60
/* prob of departure of car */
#define DEPARTURE_PERCENT_ACTION 40
/* thread sleep time between arrivals/departures */
#define TIME_OUT_SLEEP 500
/* generates a random number between min and max inclusive */
#define RAND(min,max) ((min)+(int)((double)(max-min+1)*rand()/(RAND_MAX+1.0)))
/* length of a car id */
#define CAR_SIZE 12
#define CARID_NUMBER_MIN 10000000
#define CARID_NUMBER_MAX 99999999


/* An example of the data structure of the Car Park. You may define your own car park */
struct Car{
	char *id;
	struct tm * timestamp;
};
	

struct CarPark{
    struct Car Cars[CAR_PARK_SIZE];		//car array representing the carpark
    int  keep_running;		         // set false to exit threads
    int  current_size;			 // current size of carpark
};


/* Examples of function prototypes, you may define your own functions */

void *monitor(void *arg);
void *arrival_queue(void *arg);
void *enter_carpark(void *arg);
void *departure(void *arg);
void add_car(struct Car *car);
void remove_car();
void show_cars();struct Car *new_car();
int  thread_sleep(int time_out_ms);
struct tm *get_time();
char get_key();
void exit_with_error(char *message);

pthread_mutex_t carpark_mutex;
sem_t carpark_empty;
sem_t carpark_full;
struct CarPark car_park;

int main()
{
	pthread_t arivalThread;
	pthread_t carparkEnterThread;
	pthread_t departureThread;
	pthread_t monitorThread;
	char enter[10];
	sem_init(&carpark_empty,0,CAR_PARK_SIZE);
	sem_init(&carpark_full,0,0);
	pthread_mutex_init(&carpark_mutex, NULL);
	
	car_park.keep_running = 1;
	car_park.current_size = 0;
	printf("\nWelcome to the Phoenix Car Park Simulation\nPress'C/c' (followed by enter) to show car park status\nPress 'Q/q'(followed by enter) to quit the program\n----Press Enter to continue----\n");
	fgets(enter,10,stdin);
	if(pthread_create(&arivalThread, NULL, arrival_queue, &car_park))
	{
		printf("error creating thread");
		abort();
	}
	if(pthread_create(&carparkEnterThread, NULL, enter_carpark, &car_park))
	{
		printf("error creating thread");
		abort();
	}
	if(pthread_create(&departureThread, NULL, departure, &car_park))
	{
		printf("error creating thread");
		abort();
	}
	if(pthread_create(&monitorThread, NULL, monitor, &car_park))
	{
		printf("error creating thread");
		abort();
	}
    if ( pthread_join(arivalThread, NULL) )
    {
        printf("error joining arival thread");
        abort();
    }
    if ( pthread_join(carparkEnterThread, NULL) )
    {
        printf("error joining enter thread");
        abort();
    }
    if ( pthread_join(departureThread, NULL) )
    {
        printf("error joining departure thread");
        abort();
    }
    if ( pthread_join(monitorThread, NULL) )
    {
        printf("error joining monitor thread");
        abort();
    }
}
void *monitor(void *arg)
{
	char input[10];
	while(car_park.keep_running == 1)
	{
		
		fgets(input,10,stdin);
		pthread_mutex_lock(&carpark_mutex);
		if(input[0] == 'c' || input[0] == 'C')
		{
			
			/*show_cars();*/
		}
		if(input[0] =='q' || input[0] == 'Q')
		{			
			car_park.keep_running = 0;
			
		}
		pthread_mutex_unlock(&carpark_mutex);
	}
}
void *departure(void *arg)
{
	
}
void *arrival_queue(void *arg){}
void *enter_carpark(void *arg){}

